const puppeteer = require('puppeteer-extra')
const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha')
const config  = require('../config/config');

const keys = ['led','iphone','lv','ksi','option'];

class merchant_login{
    constructor(username,password) {
        this.username = username;
        this.password = password;
        this.page = null;
        this.browser = null;
        this.cookie = null;
    }

    async initPageModule(){

        //使用插件
        puppeteer.use(
            RecaptchaPlugin({
                provider: {
                    id: config.CAPTCHA.ID,
                    token: config.CAPTCHA.API_KEY,
                },
                visualFeedback: true,
            })
        );

        //构建内核对象
        this.browser = await puppeteer.launch({
            headless:true,
            timeout:60000,
            defaultViewport: {
                width: 0,
                height: 0
            },
            args: ['--no-sandbox', '--disable-setuid-sandbox'],
            ignoreDefaultArgs: [
                '--enable-automation',
            ]
        });

        this.page = await this.browser.newPage();
        //伪装真实浏览器
        await this.camouflageBrowser();
    }

    async crackRobot(){
        //开始识别google 机器人
        await this.page.solveRecaptchas();
    }

    async camouflageBrowser(){
        this.page.setRequestInterception(true);
        //设置不加载图片
        this.page.on('request',async (request) => {
            // 如果文件类型为image,则中断加载
            if (request.resourceType() === 'image') {
                request.abort();
                return;
            }
            // 正常加载其他类型的文件
            request.continue();
        });
        await this.page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36');

        //删掉webdriver属性 以免被检测出为无头浏览器
        await this.page.evaluateOnNewDocument(() => {
            const newProto = navigator.__proto__;
            delete newProto.webdriver;
            navigator.__proto__ = newProto;
        });

        //无头浏览器模式下,全局对象下的chrome对象是没有 runtime属性的
        await this.page.evaluateOnNewDocument(() => {
            window.navigator.chrome = {
                runtime: {}
            };
        });
    }


    /**
     * 打开登录页
     * @returns {Promise<void>}
     */
    async openLoginPage(){
        let loginUrl = 'https://www.merchantwords.com/login/';
        try {
            await this.page.goto(loginUrl,{timeout: 0,waitUntil: ["domcontentloaded"]});
        } catch (e) {
            throw new Error(`打开页面超时...`);
        }
        console.log(`打开页面成功`)
    }

    /**
     * 输入账号密码
     * @returns {Promise<void>}
     */
    async doLogin(){

        await this.page.type('#field-email-3\\#',this.username);
        await this.page.type('#field-pass-3\\#',this.password);
        console.log(`账户密码输入完毕 userName:${this.username} password:${this.password}`);
        console.log(`开始破解机器人验证...`);
        //识别验证码
        await this.crackRobot();
        console.log(`破解成功 开始登陆...`);

        await Promise.all([
            //点击登录按钮
            this.page.waitForNavigation({
                timeout:0,
                waitUntil: 'domcontentloaded',
            }),
            this.page.click('#submitButton'),
        ]);
        // this.page.type('#usersearchbox',(await this.getRandomKeywords()),{ delay: 1000 }),
        await this.page.type('#usersearchbox','led',{ delay: 200 })
        //模拟回车键
        await Promise.all([
            this.page.waitForNavigation({
                timeout:0,
                waitUntil: 'domcontentloaded',
            }),
            this.page.click('body > div.wrapper.wrapper--myaccount > div.bar-search.bar-search-advanced--clean > div > form > div > button'),
        ]);
        await this.page.goto('https://www.merchantwords.com/emerging-trends');
        console.log(`<<<<魔词登录成功>>>>`);
        let cks = await this.page.cookies();
        // cookiesStr = cookiesStr.replace(/\ +/g,"");
        // cookiesStr = cookiesStr.replace(/[\r\n]/g,"")
        return cks.map(cookie => `${cookie.name}=${cookie.value}`).join(";");
    }

    async getRandomKeywords(){
        let index = await this.getRandomInt(keys.length);
        return keys[index];
    }

    async getRandomInt(max) {
        return Math.floor(Math.random() * max);
    }

    async do(){
        //初始化模型对象
        return new Promise(async (resolve, reject) => {
            await this.initPageModule();
            //打开登录页
            await this.openLoginPage().then(async () => {
                //登录
                await this.doLogin().then((ck) => {
                    resolve(ck);
                }).catch((e) => {
                    console.log(`[魔词登录] => 失败 e:${e.message}`)
                    reject()
                }).finally(async () => {
                    console.log(`[魔词登录] => 关闭浏览器`);
                    await this.closeBrowser();
                });

            }).catch(async (error) => {
                console.log(`[魔词登录] => ${error.message}`);
                await this.closeBrowser();
                reject()
            });

        })
    }

    async closeBrowser(){
        let pages = await this.browser.pages();
        await Promise.all(pages.map(page =>page.close()));
        await this.browser.close();
    }

}
module.exports = merchant_login;
